package main

import "fmt"

// Go语言的指针是安全指针, 不能进行偏移和运算(区别于c/c++的指针)
// 只需要记住两个符号即可: & 取地址，* 根据地址取值
func main() {
	a := 10
	b := &a
	fmt.Println(a, b)
	fmt.Printf("a: %d, b: %p\n", a, b)
	fmt.Printf("b: %p, b: %T\n", b, b) // %p指针, %T类型
	fmt.Println(&b, *b)

	// 空指针: nil
	var p *string
	fmt.Println(p)
	//fmt.Printf("p的值是%s\n", p) // panic: runtime error: invalid memory address or nil pointer dereference
	if p != nil {
		fmt.Println("非空")
	} else {
		fmt.Println("空值")
	}

	// new和make
	// new函数不太常用，使用new函数得到的是一个类型的指针，并且该指针对应的值为该类型的零值
	// make也是用于内存分配的，区别于new，它只用于slice、map以及chan的内存创建，
	//     而且它返回的类型就是这三个类型本身，而不是他们的指针类型，
	//     因为这三种类型就是引用类型，所以就没有必要返回他们的指针了
	c1 := new(int)
	c2 := new(bool)
	fmt.Printf("%T\n", c1) // *int
	fmt.Printf("%T\n", c2) // *bool
	fmt.Println(*c1)       // 0
	fmt.Println(*c2)       // false

	var d map[string]int
	d = make(map[string]int, 10)
	d["测试"] = 100
	fmt.Println(d)
}
